Trust resolved version over declared dep in dependency search#181
Merged
Conversation
PR #179 extended ModuleHasDependency / RepositoryHasDependency to also match against requested/declared dependencies so they still match when resolution fails. This introduced false positives whenever a version range is supplied: the declared version string could satisfy the comparator even when the resolved version did not (e.g. a Gradle resolutionStrategy.force or platform alignment overriding the declared coordinate). - When a coordinate is present in the resolved dependencies, trust the resolved check and skip the declared-dependency fallback for that group:artifact. Only fall back for declared deps not already resolved. - Tighten versionMatches so a null declared version no longer auto-matches when a version constraint is supplied (same treatment as a ${...} property reference). Adds regression tests covering both rules in ModuleHasDependencyTest and RepositoryHasDependencyTest.
Jenson3210
reviewed
May 29, 2026
Jenson3210
reviewed
May 29, 2026
Jenson3210
reviewed
May 29, 2026
Jenson3210
reviewed
May 29, 2026
Co-authored-by: Jente Sondervorst <jentesondervorst@gmail.com>
Jenson3210
approved these changes
May 29, 2026
Contributor
Jenson3210
left a comment
There was a problem hiding this comment.
Added the failing maven tests and this should now fix the downstream failure + other mismatches
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
PR Match requested dependencies in ModuleHasDependency and RepositoryHasDependency #179 (
ad8dbec) extendedModuleHasDependencyandRepositoryHasDependencyto also match against requested/declared dependencies, so they still match when dependency resolution fails (e.g. no repositories configured). As reported inrewrite-third-party#76, this introduced false positives whenever a version range is supplied:If the project resolves, the resolved version is the source of truth. But the new code unconditionally also walked the declared dependencies, and the literal declared version string can satisfy the comparator even when the resolved version does not (BOM-managed versions, Gradle
resolutionStrategy.force, platform alignment, etc.).A
nulldeclared version (versionMatches(null, cmp)) silently matched any constraint.Fix
groupId:artifactIdcoordinates. When iterating requested/declared dependencies, skip any whose GA is already resolved. This preserves the "match on declared when not resolved" behaviour from Match requested dependencies in ModuleHasDependency and RepositoryHasDependency #179 while preventing the version-range false positive.versionMatches. Anulldeclared version no longer auto-matches when a version constraint is supplied (same treatment as a${...}property reference).Applied identically to both
ModuleHasDependencyandRepositoryHasDependency.Tests
gradleMatchesOnRequested,mavenMatchesOnRequested,gradleVersionRangeOnRequestedDoesNotMatchWhenOutOfRange) still pass.gradleVersionRangeDoesNotMatchDeclaredWhenResolvedVersionIsOutOfRange(rule 1):resolutionStrategy.forceresolves out-of-range while the declared version is in-range → no match. Verified to fail without the dedup fix.gradleRequestedWithoutVersionAndConstraintDoesNotMatch(rule 2): declared dep with no version + a constraint → no match. Verified to fail without theversionMatcheschange.ModuleHasDependencyTestandRepositoryHasDependencyTest.Note: a Maven analogue for rule 1 is not included — in Maven an explicit declared
<version>on a direct dependency always wins over<dependencyManagement>/BOM, so the resolved version equals the declared version and no divergence (hence no false positive) is reproducible for a direct dep. The divergence is a Gradle phenomenon (force/platform/alignment)../gradlew checkpasses.